home *** CD-ROM | disk | FTP | other *** search
/ Programming Microsoft Visual Basic .NET / Programming Microsoft Visual Basic .NET (Microsoft Press)(X08-78517)(2002).bin / setup / vbnet / 04 class fundamentals / classesdemo / module1.vb < prev    next >
Encoding:
Text File  |  2002-03-16  |  19.0 KB  |  560 lines

  1. Option Strict Off
  2.  
  3. Module MainModule
  4.  
  5.     Sub Main()
  6.         ' Run one of the Textxxxx procedures below by uncommenting only one statement
  7.  
  8.         'TestByrefPassing()
  9.         'TestOverloadedFunctions()
  10.         'TestByRefProperty()
  11.         'TestDefaultProperty()
  12.         'TestFinalize()
  13.         'TestFinalize2()
  14.         'TestFinalize3()
  15.         'TestDispose()
  16.         'TestGeneration()
  17.         'TestWeakReferences()
  18.         'TestWithEvents()
  19.         'TestAddHandler()
  20.         'TestWithEvents2()
  21.         'TestAddHandler2()
  22.         'TestWithEvents3()
  23.         'TestAddHandler3()
  24.         'TestModuleEvents()
  25.         'TestArrayEvents()
  26.         'TestNewEventSyntax()
  27.         'TestSharedFields()
  28.         'TestSharedMembers()
  29.         'TestSharedMembers2()
  30.         'TestSharedConstructors()
  31.         'TestSharedEvents()
  32.         'TestSharedEvents2()
  33.  
  34.         ' You need these statements when running inside Visual Studio, so that
  35.         ' the Console window doesn't disappear
  36.         Console.WriteLine("")
  37.         Console.WriteLine(">>> press Enter to terminate the program <<<")
  38.         Console.ReadLine()
  39.  
  40.     End Sub
  41.  
  42.     ' A code snippet that passes the Power4 function
  43.     ' a Public variable defined in a class.
  44.  
  45.     Sub TestByrefPassing()
  46.         Dim obj As New SampleClass()
  47.         obj.Number = 3
  48.         Console.WriteLine(Power4(obj.Number))  ' => 81
  49.         ' The Number property has changed as well.
  50.         Console.WriteLine(obj.Number)          ' => 9
  51.  
  52.         ' Do it again, but this time pass the argument ByVal
  53.         obj.Number = 3
  54.         Console.WriteLine(Power4((obj.Number)))  ' => 81
  55.         ' The Number property hasn't changed .
  56.         Console.WriteLine(obj.Number)          ' => 3
  57.     End Sub
  58.  
  59.     ' Test the overloaded Sum functions
  60.  
  61.     Sub TestOverloadedFunctions()
  62.         Dim intValue As Short = 1234
  63.         ' This statement invokes the integer version.
  64.         Console.WriteLine(Sum(intValue, 1))    ' => 1235
  65.  
  66.         ' This statement invokes the floating point version.
  67.         Console.WriteLine(Sum(intValue, 1.25!))    ' => 1235.25
  68.  
  69.         Dim dblValue As Double = 1234
  70.         ' *** The next statement raises a compiler error.
  71.         ' Console.WriteLine(Sum(dblValue, 1.25))
  72.     End Sub
  73.  
  74.     ' this procedure cehcks that ByRef properties indeed work
  75.  
  76.     Sub TestByRefProperty()
  77.         Dim vc As New ValueClass()
  78.         vc.DoubleValue = 100
  79.         ClearValue(vc.DoubleValue)
  80.         Console.WriteLine(vc.DoubleValue)           ' => 0
  81.         vc.DoubleValue += 10
  82.         Console.WriteLine(vc.DoubleValue)           ' => 10
  83.     End Sub
  84.  
  85.     ' this routine is used by previous test procedure
  86.  
  87.     Sub ClearValue(ByRef Value As Double)
  88.         Value = 0
  89.     End Sub
  90.  
  91.     ' this procedure tests default properties
  92.  
  93.     Sub TestDefaultProperty()
  94.         ' Set a note for a person.
  95.         Dim aPerson As New Person()
  96.         aPerson.FirstName = "Joe"
  97.         ' Prove that Notes is the default property.
  98.         aPerson(0) = "Remind Joe to review the proposal"
  99.         aPerson(2) = "Joe's birthday is on June 5"
  100.  
  101.         ' Display all the notes.
  102.         Dim i As Integer
  103.         For i = 0 To 9
  104.             Console.WriteLine(aPerson(i))
  105.         Next
  106.     End Sub
  107.  
  108.     ' test the Finalize method
  109.  
  110.     Sub TestFinalize()
  111.         Console.WriteLine("About to create a Person object.")
  112.         Dim aPerson As New Person2("Joe", "Doe")
  113.         Console.WriteLine("Exiting the TestFinalize procedure.")
  114.         ' NOTE: you should see a message from inside the Finalize method 
  115.         ' here, but you don't. You see it only when the application ends.
  116.     End Sub
  117.  
  118.     ' Show that creating many objects eventually fires a garbage collection.
  119.  
  120.     Sub TestFinalize2()
  121.         Dim i As Integer
  122.         ' NOTE: If no Finalize method is invoked on your system, 
  123.         ' increment the loop upper limit.
  124.         For i = 1 To 10000
  125.             TestFinalize_Create()
  126.         Next
  127.         Debug.WriteLine("About to terminate the application.")
  128.     End Sub
  129.  
  130.     ' support routine for previous test procedure
  131.     Sub TestFinalize_Create()
  132.         Dim aPerson As New Person2("Joe", "Doe")
  133.     End Sub
  134.  
  135.     ' demonstrate the GC.Collect method.
  136.  
  137.     Sub TestFinalize3()
  138.         ' create and destroy an object
  139.         Debug.WriteLine("About to create a Person object.")
  140.         Dim aPerson As New Person2("Joe", "Doe")
  141.         aPerson = Nothing
  142.  
  143.         ' force a garbage collection and wait for Finalizers to complete
  144.         Debug.WriteLine("About to fire a garbage collection.")
  145.         GC.Collect()
  146.         GC.WaitForPendingFinalizers()
  147.     End Sub
  148.  
  149.     ' This procedure shows how to use an object that exposes a Dispose method.
  150.  
  151.     Sub TestDispose()
  152.         ' Create the object.
  153.         Dim obj As New Widget()
  154.         ' Use the object.
  155.         ' ...
  156.  
  157.         ' Clean-up code.
  158.         obj.Dispose()
  159.     End Sub
  160.  
  161.     ' this procedure tests the GC.GetGeneration method
  162.  
  163.     Sub TestGeneration()
  164.         Dim s As String = "dummy string"
  165.  
  166.         ' This is a 0-generation object.
  167.         Console.WriteLine(GC.GetGeneration(s))   ' => 0
  168.         ' Make it survive to a first GC.
  169.         GC.Collect()
  170.         Console.WriteLine(GC.GetGeneration(s))   ' => 1
  171.         ' Make it survive to a second GC.
  172.         GC.Collect()
  173.         Console.WriteLine(GC.GetGeneration(s))   ' => 2
  174.         ' Any subsequent GC doesn't increment the generation counter.
  175.         GC.Collect()
  176.         Console.WriteLine(GC.GetGeneration(s))   ' => 2
  177.     End Sub
  178.  
  179.     ' This procedure shows how you can use the WeakReference object.
  180.  
  181.     Sub TestWeakReferences()
  182.         ' Evaluate all prime numbers in the range 1-1000
  183.         Dim pn As New PrimeNumbers(1000)
  184.         ' Check whether 11 is a prime number.
  185.         Console.WriteLine(pn.IsPrime(11))     '  => True
  186.  
  187.         ' We aren't going to use the object for a while, so let's make it
  188.         ' weakly-referenced, and eligible for a garbage collection.
  189.         Dim pnWR As New WeakReference(pn)
  190.         pn = Nothing
  191.  
  192.         ' Attempt to get a strong reference again.
  193.         pn = CType(pnWR.Target, PrimeNumbers)
  194.         If pn Is Nothing Then
  195.             ' We must recreate the object from scratch.
  196.             ' (This time this statement *isn't* executed)
  197.             pn = New PrimeNumbers(100)
  198.         End If
  199.         ' Check whether 71 is prime.
  200.         Console.WriteLine(pn.IsPrime(71))     ' => True
  201.  
  202.         ' repeat the entire sequence, but now simulate a GC
  203.  
  204.         ' clear the strong reference
  205.         pn = Nothing
  206.  
  207.         ' fire a garbage collection
  208.         GC.Collect()
  209.         GC.WaitForPendingFinalizers()
  210.  
  211.         ' Attempt to get a strong reference again.
  212.         pn = CType(pnWR.Target, PrimeNumbers)
  213.         If pn Is Nothing Then
  214.             ' We must recreate the object from scratch.
  215.             ' (This time this statement *is* executed)
  216.             pn = New PrimeNumbers(100)
  217.         End If
  218.         ' Check whether 71 is prime.
  219.         Console.WriteLine(pn.IsPrime(71))     ' => True
  220.     End Sub
  221.  
  222.     ' This procedure causes some events to be fired.
  223.  
  224.     Dim WithEvents Log As Logger
  225.  
  226.     Sub TestWithEvents()
  227.         ' (we might have used New in the Dim clause)
  228.         Log = New Logger()
  229.  
  230.         Log.OpenFile()
  231.         Log.ReadData()
  232.         Log.CloseFile()
  233.     End Sub
  234.  
  235.     ' an event handler for the Log.LogAction event
  236.  
  237.     Sub LogActionEvent(ByVal actionName As String) Handles Log.LogAction
  238.         Console.WriteLine("LogAction event: " & actionName)
  239.     End Sub
  240.  
  241.     ' two variables without the WithEvents keyword, that will raise events
  242.     ' thanks to the AddHandler command.
  243.     Dim Log1 As Logger
  244.     Dim Log2 As Logger
  245.  
  246.     Sub TestAddHandler()
  247.         ' (we might have used New in the Dim clause)
  248.         Log1 = New Logger()
  249.         Log2 = New Logger()
  250.  
  251.         ' Connect to an event handler dynamically.
  252.         AddHandler Log1.LogAction, AddressOf LogActionEvent2
  253.         AddHandler Log2.LogAction, AddressOf LogActionEvent2
  254.  
  255.         ' Cause some events to be fired.
  256.         Log.OpenFile()
  257.         Log.ReadData()
  258.         Log.CloseFile()
  259.  
  260.         ' Detach event handlers.
  261.         RemoveHandler Log1.LogAction, AddressOf LogActionEvent2
  262.         RemoveHandler Log2.LogAction, AddressOf LogActionEvent2
  263.     End Sub
  264.  
  265.     ' Note that no Handles clause is used here.
  266.     Sub LogActionEvent2(ByVal actionName As String)
  267.         Console.WriteLine("LogAction event: " & actionName)
  268.     End Sub
  269.  
  270.     ' This procedure shows the behavior of events trapped through a
  271.     ' WithEvents variable when the variable is set to Nothing.
  272.     Sub TestWithEvents2()
  273.         ' (we might have used New in the Dim clause)
  274.         Log = New Logger()
  275.  
  276.         ' Create another variable that points to the same object.
  277.         Dim logobj As Logger = Log
  278.  
  279.         ' These statements raise three events, even though we access
  280.         ' the object through the new variable.
  281.         logobj.OpenFile()
  282.         logobj.ReadData()
  283.         logobj.CloseFile()
  284.  
  285.         ' Clear the WithEvents variable.
  286.         Log = Nothing
  287.         ' These statements don't raise any event, because the event handler
  288.         ' is tied to the WithEvents variable, not the object.
  289.         logobj.OpenFile()
  290.         logobj.ReadData()
  291.         logobj.CloseFile()
  292.     End Sub
  293.  
  294.     ' This procedure shows the behavior of events trapped through a
  295.     ' the AddHandler command when the variable is set to Nothing.
  296.     Sub TestAddHandler2()
  297.         ' (we might have used New in the Dim clause)
  298.         Log2 = New Logger()
  299.  
  300.         ' Enable the event handler.
  301.         AddHandler Log2.LogAction, AddressOf LogActionEvent2
  302.         ' Create another variable that points to the same object.
  303.         Dim logobj As Logger = Log2
  304.  
  305.         ' These statements raise three events, even though we access
  306.         ' the object using the new variable.
  307.         logobj.OpenFile()
  308.         logobj.ReadData()
  309.         logobj.CloseFile()
  310.  
  311.         ' Clear the WithEvents variable.
  312.         Log2 = Nothing
  313.         ' These statements raise three events as well, because handlers created
  314.         ' with AddHandler are tied to the object, not a specific variable.
  315.         logobj.OpenFile()
  316.         logobj.ReadData()
  317.         logobj.CloseFile()
  318.     End Sub
  319.  
  320.     ' This procedure demonstrates that you can't have events from a WithEvents variable
  321.     ' after you set it to Nothing.
  322.  
  323.     Sub TestWithEvents3()
  324.         ' (we might have used New in the Dim clause)
  325.         Log = New Logger()
  326.  
  327.         ' This raises an event.
  328.         Log.OpenFile()
  329.  
  330.         ' Clear the WithEvents variable (and logically destroy the object).
  331.         Log = Nothing
  332.         ' Force the Finalize method û we get no event, because the
  333.         ' event handler is tied to the variable, not the object.
  334.         GC.Collect()
  335.     End Sub
  336.  
  337.  
  338.     ' This procedure demonstrates that you can get events from a variable
  339.     ' whose event handlers have been created with AddHandler, even after
  340.     ' you set the variable to Nothing
  341.  
  342.     Sub TestAddHandler3()
  343.         ' (we might have used New in the Dim clause)
  344.         Log2 = New Logger()
  345.  
  346.         ' Create the event handler dynamically with AddHandler.
  347.         AddHandler Log2.LogAction, AddressOf LogActionEvent2
  348.         ' This raises an event.
  349.         Log2.OpenFile()
  350.  
  351.         ' Clear the variable (and logically destroy the object).
  352.         Log2 = Nothing
  353.         ' Force the Finalize method û we do get one additional event because
  354.         ' the event handler is tied to the object, not the variable.
  355.         GC.Collect()
  356.     End Sub
  357.  
  358.     ' This procedure proves that you can trap events raised by modules.
  359.  
  360.     Private Sub TestModuleEvents()
  361.         ' Install the event handlers.
  362.         AddHandler FileOperations.Notify_CopyFile, AddressOf NotifyCopy
  363.         AddHandler FileOperations.Notify_DeleteFile, AddressOf NotifyDelete
  364.  
  365.         ' Create a copy of Autoexec.bat and then delete it.
  366.         CopyFile("c:\autoexec.bat", "c:\autoexec.$$$")
  367.         DeleteFile("c:\autoexec.$$$")
  368.  
  369.         ' Detach the event handlers.
  370.         RemoveHandler FileOperations.Notify_CopyFile, AddressOf NotifyCopy
  371.         RemoveHandler FileOperations.Notify_DeleteFile, AddressOf NotifyDelete
  372.     End Sub
  373.  
  374.     ' These procedures log the file operation to the Debug window.
  375.     Sub NotifyCopy(ByVal source As String, ByVal destination As String)
  376.         Console.WriteLine(source & " copied to " & destination)
  377.     End Sub
  378.  
  379.     Sub NotifyDelete(ByVal filename As String)
  380.         Console.WriteLine(filename & " deleted")
  381.     End Sub
  382.  
  383.     ' This procedure demonstrates how you can trap events from arrays of objects
  384.  
  385.     Dim Persons() As Person3 = {New Person3("Joe", "Doe"), _
  386.         New Person3("Robert", "Smith"), _
  387.         New Person3("Ann", "Ross")}
  388.  
  389.     Sub TestArrayEvents()
  390.         ' Have the GotMail procedure serve all the objects in Persons.
  391.         Dim p As Person3
  392.         For Each p In Persons
  393.             AddHandler p.GotEmail, AddressOf GotEmailEvent
  394.         Next
  395.  
  396.         ' Send two emails and check that two events are raised.
  397.         Persons(0).SendEmail("Sample email #1")
  398.         Persons(2).SendEmail("Sample email #2")
  399.     End Sub
  400.  
  401.     Private Sub GotEmailEvent(ByVal p As Person3, ByVal msgText As String)
  402.         Console.WriteLine(p.CompleteName & " got this message: " & msgText)
  403.     End Sub
  404.  
  405.     ' This procedure demonstrates the VB.NET preferred syntax for events
  406.  
  407.     Dim WithEvents joe As New Person4("Joe", "Doe")
  408.  
  409.     Sub TestNewEventSyntax()
  410.         ' Create another Person4 object (Joe's wife).
  411.         Dim ann As New Person4("Ann", "Smith")
  412.  
  413.         ' Test the Married event.
  414.         joe.Spouse = ann
  415.  
  416.         ' Let Ann give Joe a gift, and test the GotGift event.
  417.         joe.GiveGift(ann, "a book")
  418.     End Sub
  419.  
  420.     Sub Married(ByVal sender As Object, ByVal e As System.EventArgs) _
  421.         Handles joe.Married
  422.         ' Get a strong-typed reference to the object which raised the event.
  423.         Dim p As Person4 = CType(sender, Person4)
  424.         Console.WriteLine(p.CompleteName() & " married " & p.Spouse.CompleteName())
  425.     End Sub
  426.  
  427.     Sub GotGift(ByVal sender As Object, ByVal e As GotGiftEventArgs) _
  428.         Handles joe.GotGift
  429.         ' Get a strong-typed reference to the object which raised the event
  430.         ' (that is, the Person4 who got the gift).
  431.         Dim p As Person4 = CType(sender, Person4)
  432.         Console.WriteLine(e.Giver.CompleteName() & " gave " & p.CompleteName() _
  433.         & " the following gift: " & e.GiftDescription)
  434.     End Sub
  435.  
  436.     ' This procedure demonstrates shared fields 
  437.  
  438.     Sub TestSharedFields()
  439.         Dim inv1 As New Invoice()
  440.         Console.WriteLine("ID of first Invoice object: " & inv1.Id)   ' => 1
  441.  
  442.         Dim inv2 As New Invoice()
  443.         Console.WriteLine("ID of second DataFile object: " & inv2.Id)   ' => 2
  444.     End Sub
  445.  
  446.     ' this procedure demonstrates shared fields and methods.
  447.  
  448.     Sub TestSharedMembers()
  449.         ' create a SerialPort object.
  450.         Dim sp1 As New SerialPort()
  451.         ' check which serial port it had allocated.
  452.         Console.WriteLine("First object allocated port #" & CStr(sp1.Port))
  453.  
  454.         ' create a second SerialPort object.
  455.         Dim sp2 As New SerialPort()
  456.         ' check which serial port it had allocated.
  457.         Console.WriteLine("Second object allocated port #" & CStr(sp2.Port))
  458.  
  459.         ' now release first object
  460.         sp1.Dispose()
  461.         sp1 = Nothing
  462.         Console.WriteLine("First object has been destroyed")
  463.  
  464.         ' create a third SerialPort object.
  465.         Dim sp3 As New SerialPort()
  466.         ' check which serial port it had allocated.
  467.         Console.WriteLine("Third object allocated port #" & CStr(sp3.Port))
  468.  
  469.         ' show that we can learn which port is free using a shared method
  470.         Console.WriteLine("A new SerialPort object would allocate port #" & CStr(SerialPort.GetAvailablePort))
  471.     End Sub
  472.  
  473.     ' This procedure demonstrates shared methods 
  474.  
  475.     Sub TestSharedMembers2()
  476.         ' You can call shared methods without instancing a Triangle class
  477.         Console.WriteLine(Triangle.GetPerimeter(3, 4, 5))    ' => 12
  478.         Console.WriteLine(Triangle.GetArea(3, 4, 5))         ' => 6
  479.     End Sub
  480.  
  481.     ' this procedure tests shared constructors
  482.  
  483.     Sub TestSharedConstructors()
  484.         ' Create a new instance of the FileLogger class.
  485.         ' This also fires the Shared Sub New constructor.
  486.         Dim fl As New FileLogger()
  487.  
  488.         ' display value of shared readonly fields
  489.         Console.WriteLine("ExecutionTime: " & FileLogger.StartExecutionTime)
  490.         Console.WriteLine("Initial Directory: " & FileLogger.InitialDir)
  491.  
  492.         ' print something to the log file
  493.         fl.Log("A test string")
  494.         ' close the file
  495.         FileLogger.Close()
  496.     End Sub
  497.  
  498.     ' this procedure tests shared events
  499.  
  500.     ' Declare a triangle variable û this variable is used only to
  501.     ' trap shared events from all the instances of the Triangle class.
  502.     Dim WithEvents AnyTriangle As Triangle
  503.  
  504.     Sub TestSharedEvents()
  505.         ' (we might have used New in the Dim clause)
  506.         AnyTriangle = New Triangle()
  507.  
  508.         Dim p As Double
  509.         ' Create *another* triangle instance with invalid sides.
  510.         With New Triangle()
  511.             .Side1 = 10
  512.             .Side1 = 2
  513.             .Side3 = 3
  514.             ' This action will cause an InvalidTriangle event.
  515.             p = .Perimeter
  516.         End With
  517.  
  518.         ' Calling the shared method with invalid sides also fires
  519.         ' the InvalidTriangle event.        
  520.         p = Triangle.GetPerimeter(12, 3, 5)
  521.     End Sub
  522.  
  523.     ' The event procedure    
  524.     Sub InvalidTriangle(ByVal side1 As Double, ByVal side2 As Double, _
  525.             ByVal side3 As Double) Handles AnyTriangle.InvalidTriangle
  526.         Console.Write("These sides don't form a valid triangle: ")
  527.         Console.WriteLine(CStr(side1) & ", " & CStr(side2) & ", " & CStr(side3))
  528.     End Sub
  529.  
  530.     ' This procedure tests shared events, but doesn't use any variable
  531.     ' IMPORTANT: this technique works also if the class doesn't expose any non-shared events.
  532.  
  533.     Sub TestSharedEvents2()
  534.         ' create a handler for the InvalidTriangle shared event.
  535.         AddHandler Triangle.InvalidTriangle, AddressOf InvalidTriangle2
  536.  
  537.         Dim p As Double
  538.         ' Create *another* triangle instance with invalid sides.
  539.         With New Triangle()
  540.             .Side1 = 10
  541.             .Side1 = 2
  542.             .Side3 = 3
  543.             ' This action will cause an InvalidTriangle event.
  544.             p = .Perimeter
  545.         End With
  546.  
  547.         ' Calling the shared method with invalid sides also fires
  548.         ' the InvalidTriangle event.        
  549.         p = Triangle.GetPerimeter(12, 3, 5)
  550.     End Sub
  551.  
  552.     ' The event procedure (doesn't require the Handles keyword).
  553.     Sub InvalidTriangle2(ByVal side1 As Double, ByVal side2 As Double, ByVal side3 As Double)
  554.         Console.Write("These sides don't form a valid triangle: ")
  555.         Console.WriteLine(CStr(side1) & ", " & CStr(side2) & ", " & CStr(side3))
  556.     End Sub
  557.  
  558. End Module
  559.  
  560.